import re
import csv
import StringIO
from sets import Set

from Common.HIT import HIT
from Common.Reward import Reward

def CsvHandler(csv_file):
    result = {}
    
    try:
        rows = csv.reader(StringIO.StringIO(csv_file))
        result['rows'] = rows;
        result['isok'] = True;
    except csv.Error:
        result['isok'] = False;
        result['message'] = "There is something wrong with the uploaded file"
        
    return result;

def HITCsvHandler(csv_file, formTemplate):
    """
        Return data:
        csvHandleResult["isok"] bool type
        
        if success:
            csvHandleResult["hitdata"] hit list
            csvHandleResult["csvdata"] csv content list
        else:  
            csvHandleResult["message"] string type
        
    """
        
    csvHandleResult = CsvHandler(csv_file)
    if not csvHandleResult["isok"]:
        return csvHandleResult
        
    """
     Csv file format:
         wordcount, h1_tag,category,primary_keyword,keywordusage_primary,secondary_keyword,keywordusage_secondary
         1300,Music and Musicians from Panama,Types of Music and Musicians from Panama,Panama music,2,Panama,13
         1400,2__Music and Musicians from Panama,2__Types of Music and Musicians from Panama,2__Panama music,3,2__Panama,14
    """
    
    """
    private fields
    """
    rowheader = None
    setTags = None
    
    """
    The following fields will be returned.
    """
    previewHitData = []
    csvFileContent = []
    
    necessaryColumn = Set(['${reward}', '${time allotted}', '${no. assignments}'])
    
    for row in csvHandleResult["rows"]:
        if rowheader is None:
            """
            Check whether header have duplicate values.
            """
            setHeader = Set(row)
            rowheader = list(row)
            for i, rh in enumerate(rowheader):
                rowheader[i] = "${" + rh.strip() + "}"
                
            if len(setHeader) != len(rowheader):
                csvHandleResult["isok"] = False
                csvHandleResult["message"] = "There are duplicate header values in your csv file"
                return csvHandleResult
            
            """
            Check whether header's value same with template html data parameters
            Check: necessary column's data + html ${} tags = csv headers
            """
            p = re.compile('\${[a-zA-Z]{1}[a-zA-Z0-9_]*}')
            tags = p.findall(formTemplate)
            setTags = Set(tags)
            setNecessaryHeaderColumns = setTags | necessaryColumn
            if len(setHeader) != len(setNecessaryHeaderColumns) or len(list(setNecessaryHeaderColumns - Set(rowheader))) != 0:
                csvHandleResult["isok"] = False
                csvHandleResult["message"] = "The csv file header does not match template html data"
                return csvHandleResult
            
            csvFileContent.append(rowheader)
            
        else:
            if len(rowheader) == len(row):
                
                hit = HIT()
                """
                init hit data
                """
                
                m = map(None, rowheader, row)
                """
                generate hit data, which would be stored in session
                """
                hitQuestionForm = formTemplate
                
                """
                header would be the csv file header
                cell would be the cell value which in the header column
                """
                for header, cell in m:
                    if header=="${reward}":
                        try:
                            hit.Amount = float(cell)
                        except ValueError:
                            hit.Amount = -1
                            break;
                    else:                        
                        """
                        Replace template html data
                        """
                        hitQuestionForm = hitQuestionForm.replace(header, cell)

                if hit.Amount!=-1:                    
                    hit.QuestionForm = hitQuestionForm
                    
                    previewHitData.append(hit)
                    csvFileContent.append(row)
    
    if len(previewHitData) > 0:
        csvHandleResult["hitdata"] = previewHitData;
        csvHandleResult["csvdata"] = csvFileContent;
    else:
        csvHandleResult["isok"] = False
        csvHandleResult["message"] = "The csv file header does not match template html data"
    return csvHandleResult

